﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace Framework.Message.SMS.CMPP.Commands
{
    public class ConnectCommand : Command
    {
        #region 变量与属性
        private string _SourceAddr;
        /// <summary>
        /// 源地址，此处为SP_Id，即SP的企业代码。
        /// </summary>
        public string SourceAddr
        {
            get { return _SourceAddr; }
            set { _SourceAddr = value; }
        }

        /// <summary>
        /// 用于鉴别源地址。其值通过单向MD5 hash计算得出，表示如下：
        /// AuthenticatorSource =
        /// MD5（Source_Addr+9 字节的0 +shared secret+timestamp）
        /// Shared secret 由中国移动与源地址实体事先商定，timestamp格式为：MMDDHHMMSS，即月日时分秒，10位。
        /// </summary>
        private byte[] AuthenticatorSource
        {
            get
            {
                MD5 md5 = new MD5CryptoServiceProvider(); //创建MD5类别
                byte[] bytes = new byte[_SourceAddr.Trim().Length + 9 + _Password.Trim().Length + 10];
                int i = 0;

                ByteStringConvert.String2Bytes(_SourceAddr, MessageCoding.ASCII).CopyTo(bytes, i); //Source_ADD 就是企业代码
                i += _SourceAddr.Trim().Length;

                byte[] s_0 = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };     //9字节的0,此处当作右补0
                s_0.CopyTo(bytes, i);
                i += 9;

                Encoding.ASCII.GetBytes(_Password).CopyTo(bytes, i); ; //密码
                i += _Password.Length;

                this._Timestamp = GetTimestamp();    //取得认证码时赋值字符串
                ByteIntConvert.UInt2Bytes(uint.Parse(_Timestamp)).CopyTo(bytes, i); //10位的字符串字节数组

                return (md5.ComputeHash(bytes, 0, bytes.Length));
            }
        }

        private string _Version;
        /// <summary>
        /// 双方协商的版本号(高位4bit表示主版本号,低位4bit表示次版本号)，对于3.0的版本，高4bit为3，低4位为0
        /// </summary>
        public string Version
        {
            get { return _Version; }
            set { _Version = value; }
        }

        private string _Timestamp;
        /// <summary>
        /// 时间戳的明文,由客户端产生,格式为MMDDHHMMSS，即月日时分秒，10位数字的整型，右对齐 。
        /// </summary>
        public string Timestamp
        {
            get { return _Timestamp; }
        }

        private string _Password;

        public string Password
        {
            set
            {
                _Password = value;
            }
        }
        #endregion

        #region 构造函数
        public ConnectCommand()
            : base()
        {
        }

        public ConnectCommand(byte[] bytes)
            : base(bytes)
        {
        }

        public ConnectCommand(byte[] bytes, int startIndex)
            : base(bytes, startIndex)
        {
            
        }

        public ConnectCommand(uint sequence)
            : base(sequence)
        {
        }
        #endregion

        public override CMPPCommandType CommandType
        {
            get { return CMPPCommandType.Connect; }
        }

        public override uint BodyLength
        {
            get { return 6 + 16 + 4 + 1; }
        }

        /// <summary>
        /// 返回一个时间戳 4 字节
        /// </summary>
        /// <returns></returns>
        private string GetTimestamp()
        {
            return DateTime.Now.ToString("MMddHHmmss");
        }

        protected override void BytesTo(byte[] bytes, int startIndex)
        {
            int i = (int)CommandHeader.HeaderLength;
            base.BytesTo(bytes, startIndex);
            _SourceAddr = ByteStringConvert.Bytes2String(bytes, i, 6, MessageCoding.ASCII).TrimEnd('\0');
            i += 6;
            i += 16;
            _Version = ((int)bytes[i]).ToString();
        }

        public override byte[] ToBytes()
        {
            int i = (int)CommandHeader.HeaderLength;
            byte[] bytes = base.ToBytes();
            ByteStringConvert.String2Bytes(_SourceAddr.PadRight(6, '\0'), MessageCoding.ASCII).CopyTo(bytes, i);
            i += 6;
            AuthenticatorSource.CopyTo(bytes, i);
            i += 16;
            bytes[i] = Convert.ToByte("0x" + _Version, 16);
            i++;
            ByteIntConvert.UInt2Bytes(uint.Parse(_Timestamp)).CopyTo(bytes, i);
            return bytes;
        }
    }
}
